//Object meant for transferring the list of received messages (and
//random choices made) to the judge.

import java.io.*;
import java.math.*;
import java.util.*;

public class MessageList implements Serializable{

    HashMap<Integer, ArrayList<Object>> msgs;
    HashMap<Integer, Integer> counters;
    ArrayList<BigInteger[][]> randomness;
    ArrayList<HashMap<Integer, BigInteger>> reconsPubls;
    int pID;

    public MessageList(int pID){
        msgs = new HashMap<Integer, ArrayList<Object>>();
        counters = new HashMap<Integer, Integer>();
        randomness = new ArrayList<BigInteger[][]>();
        reconsPubls = new ArrayList<HashMap<Integer, BigInteger>>();
        for(int i = 1; i<= Utilities.n; i++){
            counters.put(i,0);
        }
        this.pID = pID;
    }

    private void writeObject(ObjectOutputStream out) throws IOException{
        out.writeObject(msgs);
        out.writeObject(counters);
        out.writeObject(randomness);
        out.writeObject(reconsPubls);
        out.writeObject(pID);
    }
    
    private void readObject(ObjectInputStream in) 
        throws IOException, ClassNotFoundException{
        msgs = (HashMap<Integer, ArrayList<Object>>)in.readObject();
        counters = (HashMap<Integer, Integer>)in.readObject();
        randomness = (ArrayList<BigInteger[][]>)in.readObject();
        reconsPubls = (ArrayList<HashMap<Integer, BigInteger>>)in.readObject();
        pID = (Integer)in.readObject();
    }
    
    public void clearMessages(){
        msgs.clear();
        resetMessageCounter();
        randomness.clear();
        reconsPubls.clear();
    }

    public void check(){
        System.out.println("======== Player "+ pID +" =============");
        for(BigInteger[][] b : randomness){
            for(int i = 1; i<= Utilities.n_prime; i++){
                //System.out.println("randomness: [" + b[0][i] + ", "+b[1][i]+"]");
            }
            //System.out.println("");
            //break;
        }
        int tmp = 0;
        for(Integer i: msgs.keySet()){
            for(Object o : msgs.get(i)){
                System.out.println("Message received from " + i + ": "+o);
                tmp++;
                if(tmp > 15)
                    break;
            }
            System.out.println("");
            tmp = 0;
        }
        System.out.println("============================");
    }

    public void add(Object o, int playerID){
        ArrayList<Object> messages = msgs.get(playerID);
        if(messages == null){
            messages = new ArrayList<Object>();
            messages.add(o);
            msgs.put(playerID, messages);         
        }
        else{
            messages.add(o);
        }
    }

    public void addRandomness(BigInteger[][] rand){
        randomness.add(rand);
    }

    public void addReconsPubl(HashMap<Integer, BigInteger> shares){
        reconsPubls.add(shares);
    }

    public HashMap<Integer, BigInteger> getReconsPubls(){
        return reconsPubls.remove(0);
    }

    public Object getNextMsg(int playerID){
        int messageCounter = counters.remove(playerID);
        Object res = msgs.get(playerID).get(messageCounter);
        messageCounter++;
        counters.put(playerID, messageCounter);
         // debugging...
//         if(playerID == 4){
//             if(res instanceof BigInteger){
//                 System.out.println("Getting a big-integer from player "+playerID+": "+res + " ---- This is player " + pID + "  -- index: " + (messageCounter-1));
//             }
//             else{
//                 System.out.println("Getting an Integer from player "+playerID+": "+res + " ---- This is player " + pID);
//             }
//         }

        return res;
    }

    public Object getMsg(int playerID, int pointer){
        return msgs.get(playerID).get(pointer);
    }

    public void resetMessageCounter(){
        counters.clear();
        for(int i = 1; i<=Utilities.n; i++){
            counters.put(i,0);
        }
    }

    public ArrayList<BigInteger[][]> getRandomness(){
        return randomness;
    }

    public int getMessageCounter(int playerID){
        return counters.get(playerID);
    }
}